﻿package  
{
	import Base.Net.NetEvent;
	
	import Common.GameDefine;
	import Common.GameNetEvent;
	import Common.GameNetManager;
	import Common.RenderManager;
	
	import battle.BattleCommand;
	import battle.BattleCreature;
	import battle.BattleData;
	import battle.BattleHandlerCommand;
	import battle.BattleHandlerInterface;
	import battle.BattleHandlerReady;
	import battle.BattleHandlerResult;
	import battle.BattleHandlerWait;
	import battle.BattlePos;
	import battle.BattleResultAction;
	import battle.BattleResultCommand;
	import battle.BattleState;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	
	import logic.GameItem;
	
	import net.PlayerNetHandler;
	
	import ui.BattleResultUIHandler;
	import ui.ChatUIHandler;
	import ui.ItemUIHandler;
	import ui.MainUIHandler;
	import ui.MapUIHandler;
	import ui.PetUIHandler;
	import ui.RoleInfoUIHandler;
	import Common.ActionManager;
	import Common.GameAction;
	
	/**
	 * ...
	 * @author ...
	 */
	public class BattleSession
	{
		
		public var type:int = GameDefine.INVALIDID;
		public var playerNum:int;
		public var petNum:int;
		public var anemyNum:int;
		public var anemyPetNum:int;
		public var pvp:int;
		public var direction:int;
		
		private var bitmapData:BitmapData = null;
		
		private var actionBmpData:Object = null;
		private var point:Point = null;
		
		private var state:int = GameDefine.INVALIDID;
		private var handler:BattleHandlerInterface = null;
		
		private var battleHandlerCommand:BattleHandlerCommand = null;
		private var battleHandlerResult:BattleHandlerResult = null;
		private var battleHandlerWait:BattleHandlerWait = null;
		private var battleHandlerReady:BattleHandlerReady = null;
		
		private var data:BattleData = null;
		
		private var mapVisible:Boolean = false;
		
		
		public function BattleSession() 
		{
			
		}
		
		public static var instance:BattleSession = null;
		public static function Instance():BattleSession
		{
			if ( instance == null )
			{
				instance = new BattleSession();
			}
			
			return instance;
		}
		
		
		
		public function init():void
		{
			point = new Point();
			
			data = BattleData.Instance();
			data.init();
			
			battleHandlerCommand = new BattleHandlerCommand();
			battleHandlerCommand.init();
			
			battleHandlerResult = new BattleHandlerResult();
			battleHandlerResult.init();
			
			battleHandlerWait = new BattleHandlerWait();
			battleHandlerWait.init();
			
			battleHandlerReady = new BattleHandlerReady();
			battleHandlerReady.init();
			
			actionBmpData = ActionManager.instance.bmpData;
			
			NetEvent.registerEvent( GameNetEvent.RECV_BATTLE_RESULT_ID , onBattleResult );
			
		}
		
		public function release():void
		{
			NetEvent.unRegisterEvent( GameNetEvent.RECV_BATTLE_RESULT_ID );
		}
		
		public function clear():void
		{
			data.clear();
			
			battleHandlerCommand.clear();
			battleHandlerResult.clear();
			battleHandlerWait.clear();
			battleHandlerReady.clear();
		}
		
		
		public function setState( s:int , escape:Boolean = false ):void
		{
			if ( s == state ) 
			{
				handler.active();
				return;
			}
			
			if ( handler )
			{
				//handler.release();
			}
			
			switch ( s ) 
			{
				case BattleState.READY:
					{
						handler = battleHandlerReady;
						ChatUIHandler.instance.enableMouse( false );
					}
					break;
				case BattleState.COMMAND:
					{
						handler = battleHandlerCommand;
					}
				break;
				case BattleState.WAIT:
					{
						handler = battleHandlerWait;
					}
				break;
				case BattleState.RESULT:
					{
						handler = battleHandlerResult;
					}
				break;	
				case BattleState.OVER:
					{
						data.fightMC.visible = false;
						GameManager.instance.endFight();
						
						if ( !escape || pvp )
						{
							BattleResultUIHandler.instance.show();
						}
						
						if ( mapVisible )
						{
							MapUIHandler.instance.visible( true );
						}
						
						MainUIHandler.instance.visible( true );
						ChatUIHandler.instance.enableMouse( true );
						
						return;
					}
				break;
			}
			
			data.fightMC.setState( s );
			handler.active();
		}
		
		public function checkState( s:int ):Boolean
		{
			return s == state;
		}
		
		public function addPet( pet:BattleCreature ):void
		{
			data.playerPetArray.push( pet );
		}
		
		public function addPlayer( player:BattleCreature ):void
		{
			data.playerArray.push( player );
		}
		
		public function addEnemy( enemy:BattleCreature ):void
		{
			data.defenderArray.push( enemy );
		}
		
		public function addEnemyPet( enemy:BattleCreature ):void
		{
			data.defenderPetArray.push( enemy );
		}
		
		public function startFight( p:int , dir:int , pNum:int , ptNum:int , aNum:int , aPNum:int ):void
		{
			type = BattleState.PVE;
			playerNum = pNum;
			petNum = ptNum;
			anemyNum = aNum;
			anemyPetNum = aPNum;
			pvp = p;
			direction = dir;
			
			if ( !data.inited )
			{
				return;
			}
			
			if ( aPNum || pvp )
			{
				data.fightMC.init( playerNum , anemyNum , true );
			}
			else
			{
				data.fightMC.init( playerNum , anemyNum , false );
			}
			
			data.fightMC.startTimer();
			
			for ( var i:int = 0 ; i < data.playerArray.length ; i++ )
			{
				data.playerArray[i].type = BattleCommand.UNDER;
				data.playerArray[i].originX = data.fightMC.playerArray[ i ].x;
				data.playerArray[i].originY = data.fightMC.playerArray[ i ].y;
			}
			
			for ( i = 0 ; i < data.playerPetArray.length ; i++ )
			{
				data.playerPetArray[i].type = BattleCommand.UP;
				data.playerPetArray[i].originX = data.fightMC.playerPetArray[ i ].x;
				data.playerPetArray[i].originY = data.fightMC.playerPetArray[ i ].y;
			}
			
			for ( i = 0 ; i < data.defenderArray.length ; i++ )
			{
				data.defenderArray[i].type = BattleCommand.UNDER;
				data.defenderArray[i].originX = data.fightMC.enemyArray[ i ].x;
				data.defenderArray[i].originY = data.fightMC.enemyArray[ i ].y;
			}
			
			for ( i = 0 ; i < data.defenderPetArray.length ; i++ )
			{
				data.defenderPetArray[i].type = BattleCommand.UP;
				data.defenderPetArray[i].originX = data.fightMC.enemyPetArray[ i ].x;
				data.defenderPetArray[i].originY = data.fightMC.enemyPetArray[ i ].y;
			}
			
			data.turn = 0;
			
			setState( BattleState.READY );
			
			SceneManager.instance.Fight( true );
			
			mapVisible = MapUIHandler.instance.isVisible;
			
			MainUIHandler.instance.closeAll();
			MainUIHandler.instance.visible( false );
		}
		
		
		public function onButtonClick( e:MouseEvent ):void
		{
			handler.onClick( e );
		}
		
		
		private function onBattleResult( a:ByteArray ):void
		{
			data.battleResultCommand.clear();
			
			data.battleResultCommand.turn = a.readByte();
			data.battleResultCommand.result = a.readByte();
			data.battleResultCommand.num = a.readByte();
			
			for ( var i:int = 0; i < data.battleResultCommand.num ; i++ )
			{
				var action:BattleResultAction = new BattleResultAction();
				
				action.attack = a.readByte();
				action.type = a.readByte();
				
				if ( direction )
				{
					action.attack = action.attack == 1 ? 0 : 1;
				}
				
				switch ( action.type )
				{
					case BattleCommand.ATTACK:
					{
						action.attackerNum = a.readByte();
						action.defenderNum = a.readByte();
						
						for (var k:int = 0; k < action.attackerNum; k++)
						{
							action.attackerType.push( a.readByte() );
							action.attacker.push( a.readByte() );
							
							if ( action.attack )
							{
								if ( action.attackerType[ action.attackerType.length - 1 ] == BattleCommand.UNDER )
								{
									data.playerArray[ action.attacker[ action.attacker.length - 1 ] ].setAction( GameAction.STAND , null );
									data.playerArray[ action.attacker[ action.attacker.length - 1 ] ].action = action.type;		
								}
								else
								{
									data.playerPetArray[ action.attacker[ action.attacker.length - 1 ] ].setAction( GameAction.STAND , null );
									data.playerPetArray[ action.attacker[ action.attacker.length - 1 ] ].action = action.type;							
								}
							}
							else
							{
								if ( action.attackerType[ action.attackerType.length - 1 ] == BattleCommand.UNDER )
								{
									data.defenderArray[ action.attacker[ action.attacker.length - 1 ] ].setAction( GameAction.STAND , null );
									data.defenderArray[ action.attacker[ action.attacker.length - 1 ] ].action = action.type;
								}
								else
								{
									data.defenderPetArray[ action.attacker[ action.attacker.length - 1 ] ].setAction( GameAction.STAND , null );
									data.defenderPetArray[ action.attacker[ action.attacker.length - 1 ] ].action = action.type;
								}
							}
						}
						
						for (var j:int = 0; j < action.defenderNum; j++)
						{
							action.defenderType.push( a.readByte() );
							action.defender.push( a.readByte() );
							
							action.resultType.push( a.readByte() );
							action.result.push( a.readShort() );
						}
					}
					break;
					case BattleCommand.DEFENCE:
					case BattleCommand.ESCAPE:
					{
						var type:int = a.readByte();
						var index:int = a.readByte();
						
						if ( action.attack )
						{
							if ( type == BattleCommand.UNDER )
							{
								data.playerArray[ index ].action = action.type;
								data.playerArray[ index ].setAction( GameAction.DEFENCE , null );
							}
							else
							{
								data.playerPetArray[ index ].action = action.type;
								data.playerPetArray[ index ].setAction( GameAction.DEFENCE , null );
							}
						}
						else
						{
							if ( type == BattleCommand.UNDER )
							{
								data.defenderArray[ index ].action = action.type;
								data.defenderArray[ index ].setAction( GameAction.DEFENCE , null );
							}
							else
							{
								data.defenderPetArray[ index ].action = action.type;
								data.defenderPetArray[ index ].setAction( GameAction.DEFENCE , null );
							}
						}
					}
					break;
					
				}
				
				data.battleResultCommand.action.push( action );
			}
			
			if ( !pvp && data.battleResultCommand.result == BattleResultCommand.BATTLEWIN )
			{
				BattleResultUIHandler.instance.clear();
				
				var numPlayer:int = a.readByte();
				
				for ( var m:int = 0; m < numPlayer; m++ )
				{
					var player:GamePlayer = GameCreatureManager.instance.getPlayer( data.playerArray[ m ].data.ID );
					var oldLevel:int = data.playerArray[ m ].data.Level;
					data.playerArray[ m ].data.Level = a.readByte();
					data.playerArray[ m ].data.LevelUpPoint = a.readShort();
					
					var tempExp:int = a.readInt();
					data.playerArray[ m ].data.EXP = a.readInt();
					data.playerArray[ m ].data.NextEXP = a.readInt();
					
					if ( oldLevel != data.playerArray[ m ].data.Level )
					{
						RoleInfoUIHandler.instance.updateData();
						RoleInfoUIHandler.instance.levelUp();
					}
						
					BattleResultUIHandler.instance.addText( data.playerArray[ m ].data.Name , tempExp , oldLevel != data.playerArray[ m ].data.Level );
				}
				
				
				var numPet:int = a.readByte();
					
				for ( m = 0 ; m < numPet ; m++ )
				{
					var pet:GamePet = GameCreatureManager.instance.getPet( a.readInt() );
					
					var oldLevelPet:int = pet.data.Level;
					pet.data.Level = a.readByte();
					pet.data.Charm = a.readByte();
					pet.data.Vitality = a.readShort();
					pet.data.Strength = a.readShort();
					pet.data.Toughness = a.readShort();
					pet.data.Dexterity = a.readShort();
					var tempExpPet:int = a.readInt();
					pet.data.EXP = a.readInt();
					pet.data.NextEXP = a.readInt();
					
					BattleResultUIHandler.instance.addText( pet.data.Name , tempExpPet , oldLevelPet != pet.data.Level );
					
					pet.updateAttr();
					
					PetUIHandler.instance.updateData();
				}
				
				var numItem:int = a.readByte();
				var mainPlayer:GamePlayer = GameManager.instance.MainPlayer;
				
				for ( m = 0 ; m < numItem ; m++ )
				{
					var item:GameItem = new GameItem();
					
					PlayerNetHandler.readItem( a , item );
					
					mainPlayer.addItem( item );
					
					BattleResultUIHandler.instance.addItem( item );
				}
				
				if ( numItem )
				{
					ItemUIHandler.instance.updateData();
					BattleResultUIHandler.instance.visibleItem();
				}
				
			}
			
			setState( BattleState.RESULT );
		}
		
		
		//////////////////////////////////////////////////////////////////////////////////////////
		// render
		
		
		
		public function setBitmapData( data:BitmapData ):void
		{
			bitmapData = data;
		}
		
		public function render():void
		{
			var fightMC:MovieClip = data.fightMC;
			var pos:BattlePos = null;
			
			for (var i:int = data.defenderArray.length - 1 ; i >= 0 ; i-- ) 
			{
				pos = data.defenderArray[ i ].getPos();
				renderObj( pos.x , pos.y , data.defenderArray[ i ] );
			}
			
			for ( i = data.defenderPetArray.length - 1 ; i >= 0 ; i-- ) 
			{
				pos = data.defenderPetArray[ i ].getPos();
				renderObj( pos.x , pos.y , data.defenderPetArray[ i ] );
			}
			
			for ( i = data.playerPetArray.length - 1 ; i >= 0 ; i-- ) 
			{
				pos = data.playerPetArray[ i ].getPos();
				renderObj( pos.x , pos.y , data.playerPetArray[ i ] );
			}
			
			for ( i = data.playerArray.length - 1 ; i >= 0 ; i-- ) 
			{
				pos = data.playerArray[ i ].getPos();
				renderObj( pos.x , pos.y , data.playerArray[ i ] );
			}
			
			fightMC = null;
		}
		
		public function renderObj( x:Number , y:Number , c:BattleCreature ):void
		{
			var textureID:int = c.ActionTextureID;
			
			if ( !actionBmpData[ textureID ] ) 
			{
				return;
			}
			
			if ( textureID != GameDefine.INVALIDID ) 
			{
				point.x = x + data.fightMC.x;
				point.y = y + data.fightMC.y;
				
				point.x += actionBmpData[ textureID ].px;
				point.y += actionBmpData[ textureID ].py;
				
				bitmapData.copyPixels( actionBmpData[ textureID ].bd , actionBmpData[ textureID ].bd.rect , point , null , null , true );
			}
			
		}
			
		public function update( delay:Number ):void
		{
			for ( var i:int = data.playerArray.length - 1 ; i >= 0 ; i-- )
			{
				data.playerArray[ i ].update( delay );
			}
			
			for ( i = data.playerPetArray.length - 1 ; i >= 0 ; i-- )
			{
				data.playerPetArray[ i ].update( delay );
			}
			
			for ( i = data.defenderArray.length - 1 ; i >= 0 ; i-- )
			{
				data.defenderArray[ i ].update( delay );
			}
			
			for ( i = data.defenderPetArray.length - 1 ; i >= 0 ; i-- )
			{
				data.defenderPetArray[ i ].update( delay );
			}
		}
		
		
	}

}